package com.yt.app.api.action.pay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.yt.app.api.action.base.BaseAction;
import com.yt.app.core.interfaces.UserOrderDetailService;
import com.yt.app.core.interfaces.UserOrderPayLogService;
import com.yt.app.core.interfaces.UserOrderService;
import com.yt.app.core.model.UserOrder;
import com.yt.app.core.model.UserOrderDetail;
import com.yt.app.core.model.UserOrderPayLog;
import com.yt.app.core.utils.Constant;
import com.yt.core.MsgBean;
import com.yt.pay.AlipayConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/**
 * Description
 * <p>
 *     支付宝支付接口
 * </p>
 * DATE 2017/10/8.
 *
 * @author liujunshi.
 */

@Controller
@Api(tags = "11.支付")
@RequestMapping("/pay/alipay")
public class AlipayNotifyController extends BaseAction{
    @Autowired
    private UserOrderService userOrderService;

    @Autowired
    private UserOrderDetailService userOrderDetailService;

    @Autowired
    private UserOrderPayLogService payLogService;

    @ApiOperation(value="支付宝-异步通知", notes = "客户端不需要调用", httpMethod = "POST")
    @RequestMapping("/notify")
    public @ResponseBody
    Object toPay(
            @ApiIgnore HttpServletRequest request,
            @ApiIgnore HttpServletResponse response
            ) {
        MsgBean msgBean = new MsgBean();
        //获取支付宝POST过来反馈信息
        Map<String,String> params = getParams(request);
        System.out.println("ALIPAY NOTIFY : " + JSONObject.toJSON(params).toString());

        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
        UserOrder userOrder = null;
        try {
            boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
            if(flag){
                String orderNo = params.get("out_trade_no");
                String amount = params.get("total_amount");
                String tradeStatus = params.get("trade_status");
                userOrder = userOrderService.getByOrderNo(orderNo);
                if(userOrder != null){
                    Long orderAmount = userOrder.getAmount();
                    if(orderAmount.toString().equals(amount.split("\\.")[0])){
                        if("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){
                            if(userOrder.getOrderStatus().equals(Constant.ORDER_STATUS.NOT_PAY.value())) {
                                userOrderService.updateOrderStatus(userOrder.getId(), Constant.ORDER_STATUS.PAID.value());
                            }
                        }else if("TRADE_CLOSED".equals(tradeStatus)) {
                            if(userOrder.getOrderStatus().equals(Constant.ORDER_STATUS.NOT_PAY.value())){
                                userOrderService.updateOrderStatus(userOrder.getId(), Constant.ORDER_STATUS.CANCEL.value());
                            }else if(userOrder.getOrderStatus().equals(Constant.ORDER_STATUS.PAID.value())) {
                                userOrderService.updateOrderStatus(userOrder.getId(), Constant.ORDER_STATUS.REFUND.value());
                            }
                        }
                        output(response, "success");
                    }else{
                        output(response, "failure");
                        System.out.println("交易金额不符!");
                    }
                }else{
                    output(response, "failure");
                    System.out.println("订单不存在!");
                }
            }
        }catch(AlipayApiException ex){
            ex.printStackTrace();
        }catch (Exception ex){
            ex.printStackTrace();
        }finally {
            addPayLog(userOrder, params);
        }
        return msgBean.returnMsg();
    }
    @ApiOperation(value="支付宝-同步返回", notes = "客户端不需要调用", httpMethod = "POST")
    @RequestMapping("/return")
    public @ResponseBody
    Object toReturn(
            @ApiIgnore HttpServletRequest request,
            @ApiIgnore HttpServletResponse response
    ) {

        Map<String,String> params = getParams(request);
        System.out.println("ALIPAY RETURN : " + JSONObject.toJSON(params).toString());
        return null;
    }

    private Map<String, String> getParams(HttpServletRequest request){
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        return params;
    }

    private void addPayLog(UserOrder userOrder, Map params) {
        try {
            UserOrderPayLog log = new UserOrderPayLog();
            log.setOrderNo(userOrder != null ? userOrder.getOrderNo() : "");
            log.setUid(userOrder != null ? userOrder.getUid() : 0l);
            log.setContent(JSONObject.toJSON(params).toString());
            log.setCreateDate(System.currentTimeMillis() / 1000);
            payLogService.insert(log);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
